<?php

defined('PHPFOX') or exit('NO DICE!');

/*
	
	Coinbase Payment Gateway for Phpfox 
	
	by Abstract Enterprises @ http://phpfoxmods.net 

*/

class Phpfox_Gateway_Api_Aecoinbase implements Phpfox_Gateway_Interface
{
	
	public $_aParam = array();
	
	public $_aCurrency = array();
	
	public $sSecret = '';
	
	public function __construct(){ 
		
		$sCurrencies = Phpfox::getParam('aecoinbase.aecoinbase_currencies');
		$aCurrencies = explode(',',trim($sCurrencies,','));
		foreach($aCurrencies as $sCurr){ 
			$this->_aCurrency[] = trim($sCurr);
		}
		
		$this->sSecret = Phpfox::getParam('aecoinbase.aecoinbase_secret_key');
	}
	
	public function set($aSetting)
	{
		$this->_aParam = $aSetting;
		if (Phpfox::getLib('parse.format')->isSerialized($aSetting['setting'])){
			$this->_aParam['setting'] = unserialize($aSetting['setting']);
		}
	}
	
	
	public function getEditForm()
	{		
		$sControllerName = Phpfox::getLib('module')->getFullControllerName();
		
		//If not AdminCP.. check rules 
		if($sControllerName != 'api.admincp/gateway/add'){ 
			if(Phpfox::getParam('aecoinbase.aecoinbase_who_can_sell') == 'site' || Phpfox::getUserParam('aecoinbase.aecoinbase_can_sell') == false){ 
				return array(); 
			}
		}
		
		return array(
			'aecoinbase_apikey' => array(
				'phrase' => Phpfox::getPhrase('aecoinbase.setting_aecoinbase_apikey'),
				'phrase_info' => Phpfox::getPhrase('aecoinbase.setting_aecoinbase_apikey_descr'), 
				'value' => (isset($this->_aParam['setting']['aecoinbase_apikey']) ? $this->_aParam['setting']['aecoinbase_apikey'] : '')
			),
		);
		
	}
	
	
	public function getForm()
	{		
		//Selling User (if applicable) 
		$iSellerId = 0;
		if(isset($this->_aParam['setting']['seller_id']) && $this->_aParam['setting']['seller_id'] > 0){ 
			$iSellerId = $this->_aParam['setting']['seller_id'];
		}
		
		//Empty Api Key 
		if(!isset($this->_aParam['setting']['aecoinbase_apikey']) || $this->_aParam['setting']['aecoinbase_apikey'] == ''){ 
			return false;
		}
		
		//Supported Currencies and Alternates 
		$bAltCurrencyFound = false;
		if(!in_array($this->_aParam['currency_code'], $this->_aCurrency)){
			if(!empty($this->_aParam['alternative_cost'])){
				$aCosts = unserialize($this->_aParam['alternative_cost']);
				foreach($aCosts as $aCost){
					$sCode = key($aCost);
					$iPrice = $aCost[key($aCost)];
					if(in_array($sCode, $this->_aCurrency)){
						$this->_aParam['amount'] = $iPrice;
						$this->_aParam['currency_code'] = $sCode;
						$bAltCurrencyFound = true;
						break;
					}
				}
				if($bAltCurrencyFound === false){
					return false;
				}
			}else{
				return false;
			}
		}
		
		//Bug in Phpfox when loading in Marketplace 
		/*$sControllerName = Phpfox::getLib('module')->getFullControllerName();*/
		$sModule = Phpfox::getLib('phpfox.request')->get('req1');
		$sModule = Phpfox::getLib('url')->reverseRewrite($sModule);
		if($sModule == 'marketplace'){ 
			if($this->_aParam['setting']['aecoinbase_apikey'] == Phpfox::getParam('aecoinbase.aecoinbase_site_apikey')){ 
				return false;
			}
		}
		
		//If Global setting for site only 
		if(Phpfox::getParam('aecoinbase.aecoinbase_who_can_sell') == 'site' && $iSellerId > 0){ 
			return false;
		}
		
		//User Group Rule here to enforce it after a user has already setup with BitPay  
		if($iSellerId > 0){
			
			$aUser = Phpfox::getLib('phpfox.database')->select('*')->from(Phpfox::getT('user'))
							->where('user_id = '. (int) $iSellerId)
							->execute('getSlaveRow');
							
			if(isset($aUser['user_id'])){
				$iUserGroupId = $aUser['user_group_id']; 
				if(Phpfox::getService('user.group.setting')->getGroupParam($iUserGroupId, 'aecoinbase.aecoinbase_can_sell') == false){  
					return false;
				}
			}
		}
		
		//$this->_aParam['is_test']
		
		//Form Values 
		$aForm = array(
			'url' => Phpfox::getLib('phpfox.url')->makeUrl('aecoinbase'),
			'param' => array(
				'type' => 'buy_now',
				'apikey' => $this->_aParam['setting']['aecoinbase_apikey'],
				'item_name' => $this->_aParam['item_name'],
				'item_number' => $this->_aParam['item_number'],
				'currency_code' => $this->_aParam['currency_code'],
				'amount' => $this->_aParam['amount'],
				'notify_url' => Phpfox::getLib('phpfox.url')->makeUrl('api.gateway.callback.aecoinbase'),
				'return' => $this->_aParam['return'],
				'cancel' => Phpfox::getLib('url')->getFullUrl(false),
			)
		);
		
		if($this->_aParam['recurring'] > 0){
	        
			$sRepeat = '';
			switch ($this->_aParam['recurring'])
	        {
	            case '1':
	                $sRepeat = 'monthly';
	                break;
	            case '2':
	                $sRepeat = 'quarterly';
	                break;
	            case '3':
	                $sRepeat = '';
	                break;
	            case '4':
	                $sRepeat = 'yearly';
	                break;              
	        }
			
			//Aecoinbase doesn't work for 6 month periods 
			if($sRepeat == ''){ return false; }
			
			$aForm['param']['type'] = 'subscription';
			$aForm['param']['repeat'] = $sRepeat;
			
			if($bAltCurrencyFound == true){
				if(!empty($this->_aParam['alternative_recurring_cost'])){
					
						$aCosts = unserialize($this->_aParam['alternative_recurring_cost']);
						$bPassed = false;
						foreach ($aCosts as $sKey => $iCost)
						{
							if ($sKey == $this->_aParam['currency_code'] && in_array($sKey, $this->_aCurrency))
							{
								$this->_aParam['recurring_cost'] = $iCost;
								if (is_array($this->_aParam['recurring_cost']))
								{
									$aRec = array_values($this->_aParam['recurring_cost']);
									$this->_aParam['recurring_cost'] = array_shift($aRec);
								}
								$bPassed = true;
								break;
							}
						}
					   
						if ($bPassed === false)
						{
							return false;
						}
				}
			}
			
			//Aecoinbase doesn't support different prices for recurring periods
			if($this->_aParam['amount'] != $this->_aParam['recurring_cost']){ return false; }
			
		}
		
		return $aForm;
	}
	
	
	public function callback()
	{
		Phpfox::log('Starting Coinbase callback');
		
		$aOrderResponse = json_decode(file_get_contents('php://input'), true);
		Phpfox::log('Json response decoded');
		
		$sSecret = Phpfox::getLib('phpfox.request')->get('cbsecret');
		
		if($sSecret == $this->sSecret){ 
		
			if(is_array($aOrderResponse) && (isset($aOrderResponse['order']) || isset($aOrderResponse['recurring_payment']))){
				
				Phpfox::log('Callback Verified');
				
				if(isset($aOrderResponse['recurring_payment'])){
					Phpfox::log('Callback Type: Recurring');
					$aResponse = $aOrderResponse['recurring_payment'];
					$aPurchase = Phpfox::getService('subscribe.purchase')->getPurchase($aParams['item_number']);
					$iTotalPaid = 0;
				}else{
					Phpfox::log('Callback Type: Order');
					$aResponse = $aOrderResponse['order'];
					$iTotalPaid = number_format(($aResponse['total_native']['cents'] / 100), 2);
				}
				
				$sItemId = $aResponse['custom']; //our id 
				$sOrderId = $aResponse['id']; //aecoinbase id
				
				Phpfox::log('CoinbaseId: '.$sOrderId);
				Phpfox::log('ItemId: '.$sItemId);
				
				$aParts = explode('|',$sItemId);
				
				//Must set price from existing invoice or will fail (recurring callbackk does not send price) 
				if(isset($aOrderResponse['recurring_payment']) && isset($aParts[1]) && $aParts[0] == 'subscribe'){
					$aPurchase = Phpfox::getService('subscribe.purchase')->getPurchase($aParts[1]);
					if(isset($aPurchase['price'])){
						$iTotalPaid = $aPurchase['price'];
					}
				}
				
				Phpfox::log('Attempting to load module: ' . $aParts[0]);
				
				if (Phpfox::isModule($aParts[0]))
				{
					Phpfox::log('Module is valid.');
					Phpfox::log('Checking module callback for method: paymentApiCallback');
					if (Phpfox::hasCallback($aParts[0], 'paymentApiCallback'))
					{
						Phpfox::log('Module callback is valid.');
						Phpfox::log('Building payment status: '.$aResponse['status']);
						
						/* 
							Order: completed, canceled
							
							Recurring: active, paused, canceled 
								
								- Not doing anything on 'paused'
								
						*/
						$sStatus = null;				
						switch ($aResponse['status'])
						{
							case 'completed':
							case 'active':
								$sStatus = 'completed';
								break;
							case 'canceled':
								$sStatus = 'cancel';
								break;
						}
						
						if($sStatus != null){
							
							if($sStatus == 'completed' || $sStatus == 'cancel'){ 
							
								Phpfox::log('Executing module callback: '.$sStatus);
								Phpfox::callback($aParts[0] . '.paymentApiCallback', array(
										'gateway' => 'aecoinbase',
										'ref' => $sOrderId,						
										'status' => $sStatus,
										'item_number' => $aParts[1],
										'total_paid' => $iTotalPaid,
									)
								);
								
							}
							
						}else{ 
							Phpfox::log('Status not recognized');
						}
					}else{ 
						Phpfox::log('Module Callback not found');
					}
				}else{ 
					Phpfox::log('Module not Valid');
				}
			}else{ 
				Phpfox::log('Callback Was Not Verified'); 
			}
		}else{
			Phpfox::log('Secret Key did not match');
		}
				
	}
}

?>